package com.xy.ddd.core.repository;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.xy.ddd.core.convertor.AbstractConvertor;
import com.xy.ddd.core.convertor.DefaultConvertor;
import com.xy.ddd.core.mapper.BaseMapper;
import com.xy.ddd.core.mapper.criteria.LogicCriteria;
import com.xy.ddd.core.model.DomainModel;
import com.xy.ddd.core.model.PageData;
import com.xy.ddd.core.po.BasePo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;

import java.util.List;

public class DefaultRepository<D extends DomainModel, P extends BasePo, Mapper extends BaseMapper<P>> implements IRepository<D, Mapper> {

    @Autowired
    private Mapper mapper;

    protected AbstractConvertor<D, P> convertor = new DefaultConvertor<D, P>(){};


    @Override
    public D findById(long id) {
        P p = mapper.selectByPrimaryKey(id);
        return convertor.convert(p);
    }

    @Override
    public List<D> find(LogicCriteria criteria) {
        if (criteria != null) {
            criteria.setEntityClass(convertor.getPoClass());
        }
        List<P> list = mapper.selectByExample(criteria);
        return convertor.convert2ModelList(list);
    }

    @Override
    public PageData<D> page(LogicCriteria criteria, long currentPage, int size) {
        if (criteria != null) {
            criteria.setEntityClass(convertor.getPoClass());
        }
        Page<D> page = PageHelper.startPage(Integer.parseInt(currentPage + ""), size);
        List<D> list = find(criteria);
        PageData<D> pageData = new PageData<D>(list, currentPage, page.getTotal());

        return pageData;
    }

    @Override
    public long saveOrUpdate(D record) {
        Assert.notNull(record, "对象不允许为空");
        P p = convertor.convert(record);
        if (p.getId() == null) {
            return mapper.insertSelective(p);
        }
        return mapper.updateByPrimaryKey(p);
    }

    @Override
    public boolean batchSave(List<D> list) {
        Assert.notNull(list, "对象不允许为空");
        List<P> poList = convertor.convert2PoList(list);
        return mapper.insertList(poList) > 0;
    }

    @Override
    public long update(D record) {
        Assert.notNull(record, "对象不允许为空");
        P p = convertor.convert(record);
        return mapper.updateByPrimaryKeySelective(p);
    }

    @Override
    public int updateByExample(D record, LogicCriteria criteria) {
        Assert.notNull(record, "对象不允许为空");
        if (criteria != null) {
            criteria.setEntityClass(convertor.getPoClass());
        }
        P p = convertor.convert(record);
        return mapper.updateByExampleSelective(p, criteria);
    }

    @Override
    public boolean batchUpdate(List<D> list) {
        Assert.notNull(list, "对象不允许为空");
        List<P> poList = convertor.convert2PoList(list);
        return mapper.batchUpdateByPrimaryKeySelective(poList) > 0;
    }

    @Override
    public boolean delete(long id) {
        return mapper.deleteByPrimaryKey(id) > 0;
    }

    @Override
    public int delete(D record) {
        Assert.notNull(record, "对象不允许为空");
        P p = convertor.convert(record);
        return mapper.delete(p);
    }

    @Override
    public int deleteByExample(LogicCriteria criteria) {
        if (criteria != null) {
            criteria.setEntityClass(convertor.getPoClass());
        }
        return mapper.deleteByExample(criteria);
    }
}
